﻿Imports Pronama.Sekatyaku
Imports Pronama.Sekatyaku.Model
Imports Pronama.NicoVideo.LiveStreaming

Public Class MainWorkflow
    Inherits SequentialWorkflowActivity

    ' TODO パラメータ受け渡し方法変更

    Private _Videos As Video()
    Public Property Videos As Video()
        Get
            Return _Videos
        End Get
        Set(ByVal value As Video())
            _Videos = value
        End Set
    End Property

    Private WithEvents _CommentServer As LiveProgramClient
    Public Property LiveProgramClient As LiveProgramClient
        Get
            Return _CommentServer
        End Get
        Set(ByVal value As LiveProgramClient)
            _CommentServer = value
        End Set
    End Property

    Private _Comments As Dictionary(Of BroadcastCommentKind, BroadcastComment)
    Public Property Comments As Dictionary(Of BroadcastCommentKind, BroadcastComment)
        Get
            Return _Comments
        End Get
        Set(ByVal value As Dictionary(Of BroadcastCommentKind, BroadcastComment))
            _Comments = value
        End Set
    End Property

    Private _PlayKind As PlayKind
    Public Property PlayKind As PlayKind
        Get
            Return _PlayKind
        End Get
        Set(ByVal value As PlayKind)
            _PlayKind = value
        End Set
    End Property


    Private VideoIndex As Integer

    Public ReadOnly Property CurrentVideo As Video
        Get
            If Videos IsNot Nothing AndAlso VideoIndex < Videos.Length Then
                Return Videos(VideoIndex)
            Else
                Return Nothing
            End If
        End Get
    End Property

    Public ReadOnly Property CurrentDateTime As DateTime
        Get
            Return DateTime.Now
        End Get
    End Property
    Private _StartDateTime As DateTime
    Public Property StartDateTime As DateTime
        Get
            Return _StartDateTime
        End Get
        Set(ByVal value As DateTime)
            _StartDateTime = value
        End Set
    End Property

    Private _Continued As Boolean
    Public ReadOnly Property Continued As Boolean
        Get
            Return _Continued
        End Get
    End Property

    Private _SecondsBeforeStart As Integer
    Public Property SecondsBeforeStart As Integer
        Get
            Return _SecondsBeforeStart
        End Get
        Set(ByVal value As Integer)
            _SecondsBeforeStart = value
        End Set
    End Property

    Private _SecondsBeforeEnd As Integer
    Public Property SecondsBeforeEnd As Integer
        Get
            Return _SecondsBeforeEnd
        End Get
        Set(ByVal value As Integer)
            _SecondsBeforeEnd = value
        End Set
    End Property


    Private LatestVotingResult As String
    Private VoteResultShowingEvent As New ManualResetEvent(False)







    Private Sub _CommentServer_CommentReceived(ByVal sender As Object, ByVal e As CommentReceivedEventArgs) Handles _CommentServer.CommentReceived
        If Not e.Comment.Text.StartsWith("/vote showresult") OrElse e.Comment.Source <> ChatSource.Broadcaster Then
            Exit Sub
        End If

        LatestVotingResult = e.Comment.Text
        VoteResultShowingEvent.Set()
    End Sub



    Private Sub codeActivity3_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)

        Dim playCommand As String
        Select Case PlayKind
            Case Sekatyaku.PlayKind.Play
                playCommand = "/play " & CurrentVideo.Id
            Case Sekatyaku.PlayKind.PlaySub
                playCommand = "/play " & CurrentVideo.Id & " sub"
            Case Sekatyaku.PlayKind.PlaySound
                playCommand = "/playsound " & CurrentVideo.Id
            Case Sekatyaku.PlayKind.PlaySoundSub
                playCommand = "/playsound " & CurrentVideo.Id & " sub"
            Case Else
                playCommand = "/play " & CurrentVideo.Id
        End Select

        Dim result = BroadcastComment(playCommand)

        If result = False Then
            _Continued = False
            VideoIndex += 1
            Exit Sub
        End If

        ShowHeader()
        If VideoIndex < Videos.Length - 1 Then
            BroadcastComment("/prepare " & Videos(VideoIndex + 1).Id)
        End If
        _Continued = True
        StartDateTime = Now

    End Sub
    Private Sub ShowHeader()

        Dim title = CurrentVideo.Title.Replace(vbCr, "").Replace(vbLf, "")
        If title.Length > 40 Then
            title = title.Substring(0, 40)
        End If
        Dim desc = CurrentVideo.Description.Replace(vbCr, "").Replace(vbLf, "")
        If desc.Length > 40 Then
            desc = desc.Substring(0, 40)
        End If

        title = System.Web.HttpUtility.HtmlDecode(title)
        desc = System.Web.HttpUtility.HtmlEncode(desc)

        Dim postDate = CurrentVideo.FirstRetrieveDateTime.ToString("yyyy-MM-dd HH:mm:ss")

        'Dim perm = String.Format( _
        '"/perm <font color=""#FF9900"">投稿日時:{0}</font><br>" & _
        '"タイトル:{1}<br>" & _
        '"<font color=""#C0C0C0"">{2}<font>", _
        'postDate, _
        'title, _
        'desc)
        Dim perm = Comments(BroadcastCommentKind.VideoInfo).Text.Replace("{date}", postDate).Replace("{title}", title).Replace("{desc}", desc)
        BroadcastComment("/perm " & perm, Comments(BroadcastCommentKind.VideoInfo).Mail)

    End Sub

    Private Sub codeActivity1_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)
        For i = 5 To 1 Step -1
            Dim perm = Comments(BroadcastCommentKind.VotingStartCountDown).Text.Replace("{sec}", i.ToString)
            'CommentServer.SendBroadcastComment(String.Format("/perm 後 {0} 秒で、『延長アンケート』を開始いたします。", i), "hidden")
            BroadcastComment("/perm " & perm, Comments(BroadcastCommentKind.VotingStartCountDown).Mail)
            Thread.Sleep(1000)
        Next

        'CommentServer.SendBroadcastComment("/vote start 『延長アンケート』&#13;引き続きこの動画を視聴しますか？（過半数以上の支持で延長） はい いいえ", "hidden hidari", 3)
        BroadcastComment("/vote start " & Comments(BroadcastCommentKind.VotingStarted).Text, Comments(BroadcastCommentKind.VotingStarted).Mail)

    End Sub

    Private Sub codeActivity2_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)
        For i = 5 To 1 Step -1
            Dim perm = Comments(BroadcastCommentKind.VotingEndCountDown).Text.Replace("{sec}", i.ToString)
            'CommentServer.SendBroadcastComment(String.Format("/perm 『延長アンケート』（締め切りまで後 {0} 秒です。）<br>引き続きこの動画を視聴しますか？（過半数以上の支持で延長）", i), "hidden")
            BroadcastComment("/perm " & perm, Comments(BroadcastCommentKind.VotingEndCountDown).Mail)
            Thread.Sleep(1000)
        Next

        VoteResultShowingEvent.Reset()

        BroadcastComment("/cls")
        BroadcastComment("/vote showresult text_per", "hidden")
        'CommentServer.SendBroadcastComment("/perm 『延長アンケート』（投票は締め切りました）<br>引き続きこの動画を視聴しますか？（過半数以上の支持で延長）", "hidden hidari", 3)
        'BroadcastComment("/perm " & Comments(BroadcastCommentKind.VotingEnded).Text, Comments(BroadcastCommentKind.VotingEnded).Mail)

        Dim result = VoteResultShowingEvent.WaitOne(New TimeSpan(0, 0, 5), False)
        VoteResultShowingEvent.Reset()

        Thread.Sleep(5000)
        BroadcastComment("/vote stop", "hidden")


        Dim match = RegularExpressions.Regex.Match(LatestVotingResult, _
                                           "^/vote showresult text_per\s+(?<per1>\d+)\s+(?<per2>\d+)")
        If match.Success AndAlso _
            Convert.ToInt32(match.Groups("per1").Value) >= 500 Then
            _Continued = True
            ShowHeader()
        Else

            _Continued = False
            VideoIndex += 1
        End If


    End Sub

    Private Sub delayActivity3_InitializeTimeoutDuration(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim sec = CurrentVideo.Length.TotalSeconds - Now.Subtract(StartDateTime).TotalSeconds
        If sec < 0 Then
            sec = 0
        End If
        DirectCast(sender, DelayActivity).TimeoutDuration = New TimeSpan(0, 0, Convert.ToInt32(sec))

        VideoIndex += 1
        _Continued = False

    End Sub

    Private Sub codeActivity4_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Select Case PlayKind
            Case Sekatyaku.PlayKind.Play, Sekatyaku.PlayKind.PlaySound
                BroadcastComment("/stop")
            Case Sekatyaku.PlayKind.PlaySub, Sekatyaku.PlayKind.PlaySoundSub
                BroadcastComment("/stop sub")
            Case Else
                BroadcastComment("/stop")
        End Select

        BroadcastComment("/clear")
    End Sub

    Private Sub codeActivity5_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)

        BroadcastComment("/prepare " & Videos(0).Id)
        BroadcastComment("/perm " & Comments(BroadcastCommentKind.Opening).Text, Comments(BroadcastCommentKind.Opening).Mail)
        Thread.Sleep(3000)
    End Sub

    Private Function BroadcastComment(ByVal text As String, Optional ByVal mail As String = "") As Boolean
        For i = 0 To 2

            Try
                If LiveProgramClient.BroadcastComment(text, mail) Then
                    Return True
                End If
                Thread.Sleep(100)

            Catch ex As Exception
                Thread.Sleep(100)

            End Try
        Next
        Return False

    End Function

    Private Sub delayActivity1_InitializeTimeoutDuration(ByVal sender As System.Object, ByVal e As System.EventArgs)
        DirectCast(sender, DelayActivity).TimeoutDuration = TimeSpan.FromSeconds(SecondsBeforeStart - 5)
    End Sub

    Private Sub delayActivity2_InitializeTimeoutDuration(ByVal sender As System.Object, ByVal e As System.EventArgs)
        DirectCast(sender, DelayActivity).TimeoutDuration = TimeSpan.FromSeconds(SecondsBeforeEnd - 5)

    End Sub
End Class
